$MOD186
$EP
NAME Main
; Main program for uPD70208 microcomputer system
;
; Author: 	Dr Tay Teng Tiow
; Address:     	Department of Electrical Engineering 
;         	National University of Singapore
;		10, Kent Ridge Crescent
;		Singapore 0511.	
; Date:   	6th September 1991
;
; This file contains proprietory information and cannot be copied 
; or distributed without prior permission from the author.
; =========================================================================
;User Main Programm

; control how the programme should react when there is timer2 and serial receive interrupt.
; default programme is to display timer message on the hyperterminal at every timer2 interrupt
;public means you want other modules to access this routine
;API
;local function:
public	serial_rec_action ;serial_rec_action is the action taken by the programme when there is a serial receive interrupt
public  timer2_action ;timer2_action is the action taken by the programme when there is timer 2 interrupt

;external function to call:
;in serial.asm
extrn	print_char:far, print_2hex:far
;in 80188.asm
extrn iodefine:far
;in timer2.asm
extrn   start_timer2:far

STACK_SEG	SEGMENT
		DB	256 DUP(?)
	TOS	LABEL	WORD
STACK_SEG	ENDS


DATA_SEG	SEGMENT
	TIMER0_MESS	DB	10,13,'TIMER2 INTERRUPT    ';ascii 10 corresponds to new line character and ascii 13 corresponds to carriage return
	T_COUNT		DB	2FH  ;initialise period to send message to hyperterminal is 1.42s. So for every 2FH number of timer interrupt, it will send to hyperterminal
	T_COUNT_SET	DB	2FH
	REC_MESS	DB	10,13,'Period to transmit the msg =     ' 
DATA_SEG	ENDS


CODE_SEG	SEGMENT

	PUBLIC		START

ASSUME	CS:CODE_SEG, SS:STACK_SEG

START:
;initialize stack area
		MOV	AX,STACK_SEG		
		MOV	SS,AX
		MOV	SP,TOS

; Initialize the on-chip pheripherals
		CALL	FAR PTR	IODEFINE
		


; ^^^^^^^^^^^^^^^^^  Start of User Main Routine  ^^^^^^^^^^^^^^^^^^
    call start_timer2 ;start timer 2
                 STI ;enable global interrupt 

NEXT:     JMP NEXT

; ^^^^^^^^^^^^^^^ End of User main routine ^^^^^^^^^^^^^^^^^^^^^^^^^


SERIAL_REC_ACTION	PROC	FAR
		PUSH	CX
		PUSH 	BX
		PUSH	DS

		MOV	BX,DATA_SEG		;initialize data segment register
		MOV	DS,BX

		CMP	AL,'<'    ;increase the period  to send message
		JNE	S_FAST

		INC	DS:T_COUNT_SET
		INC	DS:T_COUNT_SET

		JMP	S_NEXT0
S_FAST:
		CMP	AL,'>' ;decrease the period to send message
		JNE	S_RET

		DEC	DS:T_COUNT_SET
		DEC	DS:T_COUNT_SET

S_NEXT0:
		MOV	CX,22			;initialize counter for message
		MOV	BX,0

S_NEXT1:	MOV	AL,DS:REC_MESS[BX]	;print message
		call	FAR ptr print_char  ;since these are string just print_char
		INC	BX
		LOOP	S_NEXT1

		MOV	AL,DS:T_COUNT_SET	;print current period to print the message
		CALL	FAR PTR PRINT_2HEX ;since the period is in integer, convert it into ascii and transmit it
S_RET:
		POP	DS
		POP	BX
		POP	CX
		RET
SERIAL_REC_ACTION	ENDP



TIMER2_ACTION	PROC	FAR
		PUSH	AX
		PUSH	DS
		PUSH	BX
		PUSH	CX

		MOV	AX,DATA_SEG
		MOV	DS,AX
	
		DEC	DS:T_COUNT 
		JNZ	T_NEXT1 ;if the number of timer interrupt has not reached T_COUNT number, it will not transmit message to hyperterminal
		MOV	AL,DS:T_COUNT_SET
		MOV	DS:T_COUNT,AL
		
		MOV	CX,20   ;number of char to transmit
		MOV	BX,0H   ;start from index 0
		
		; transmitting message to the hyperterminal
T_NEXT0:
		MOV	AL,DS:TIMER0_MESS[BX]  ;copy the current character to transmit into AL
		INC	BX                    ;BX++
		CALL 	FAR PTR PRINT_CHAR  ;prepare the character for transmission ;Since this is string just print character.
		LOOP	T_NEXT0    ;loop until the CX has reach 0. by using loop, internally it will perform dec CX until CX reaches 0

T_NEXT1:	
		POP	CX
		POP	BX
		POP	DS
		POP 	AX
		RET
TIMER2_ACTION	ENDP


CODE_SEG	ENDS
END
